import sys

from reportlab.lib.units import inch, cm, mm, pica

import core
import resources_
import page

UNITS = {
    "inch": inch,
    "cm": cm,
    "mm": mm,
    "pica": pica
}
def resolve_size(size:str) -> float:
    size = size.split("|",1)[0:2]
    if not size:
        raise core.AppError("deck_card_size_nothing","Agh?")
    count = size[0]
    try:
        count = float(count)
    except ValueError as e:
        raise core.AppError("deck_card_size_bad_type","Deck's card_size(s)' type should be number")
    if len(size) > 1:
        unit = size[1]
        try:
            count *= UNITS[unit]
        except KeyError as e:
            raise core.AppError("deck_card_size_invalid_unit:{}".format(unit),"Invalid unit for card_size") from e
    return count

def reverse_split(text:str, sep:str, max:int) -> list:
    return [x[::-1] for x in text[::-1].split(sep,max)][::-1]

def resolve_deck(text:str) -> dict:
    result = {
        "file":"",
        "card":{
            "width":0,
            "height":0
        }
    }
    arguments = reverse_split(text,";",2)
    if len(arguments)<3:
        raise core.AppError("deck_bad_arguments","At least 3 arguments, file, width, height are required")
    result["file"] = arguments[0]
    result["card"]["width"] = resolve_size(arguments[1])
    result["card"]["height"] = resolve_size(arguments[2])
    return result
    

"""
stdin输入 card_output, app_output, deck_count
然后每行输入一个"deck_file&card_width|type&card_height|type" deck_count 次
"""

def get_arguments():
    arguments = []
    decks = []
    while True:
        argument = sys.stdin.readline().strip(" \r\n")
        if len(arguments) >= 2: # argument 现在是 deck_count
            break
        arguments.append(argument)
    try:
        deck_count = int(argument)
    except ValueError as e:
        print("fatal_invalid_deck_count")
        return "end_app"
    for i in range(deck_count):
        try:
            deck = sys.stdin.readline().strip(" \r\n")
            decks.append(resolve_deck(deck))
        except core.AppError as e:
            print("card_resolve_error:{}:{}".format(deck, e.id))
    return arguments, decks

def load_decks(decks_argument:list) -> list:
    decks = []
    for deck in decks_argument:
        try:
            decks.append(resources_.load_deck(**deck))
        except core.AppError as e:
            print("deck_load_error:{}:{}".format(deck["file"],e.id))
    return decks

def run(output_argument:list, decks_argument:list) -> None:
    decks = load_decks(decks_argument)
    i = output_argument[0]
    o = output_argument[1]
    for deck in decks:
        try:
            data = [resources_.get_card_data(i,card_name)for card_name in deck.get_cards()]
            page.gen_pdf(o, reverse_split(deck.name,".",1)[0],data,deck.card_width,deck.card_height)
        except core.AppError as e:
            print("deck_gen_error:{}:{}".format(deck.name, e.id))
        else:
            print("deck_gen_success:{}".format(deck.name))

if __name__ == "__main__":
    try:
        result = get_arguments()
        if result != "end_app": run(*result)
    except Exception as e:
        print("app_uncaught_error:{}".format(str(e)))
    except KeyboardInterrupt:
        pass